<?php
use Think\Model;

class BaseModel extends Model {
	protected $tables;

	public function __construct($name = '', $tablePrefix = '', $connection = '') {
		parent::__construct($name, $tablePrefix, $connection);
		$this->tables = $this->Tables_in_boxphp();
		$this->user_id = intval(session("user_id"));
		$this->backUrl = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

	}

	/***********所有表名******/
	public function Tables_in_boxphp() {
		$this->tables = $tables = S("Tables_in_boxphp");
		if ($tables) {
			return $tables;
		} else {
			$sql = "show tables";
			$data = M("system_gennum")->query($sql);
			foreach ($data as $one) {
				$r[] = $one['Tables_in_boxphp'];
			}
			S("Tables_in_boxphp", $r);
			$this->tables = $r;
			return $r;
		}
	}

	//开启事务
	// public function startTrans() {

	// }
	// //开启事务
	// public function commit() {

	// }
	// public function rollback() {

	// }

	public function count() {
		$key = md5(json_decode($this->options));
		$count = S($key);
		if (!is_numeric($count)) {
			$this->set_cache("select", $key);
			$count = parent::count();
		}
		return $count;
	}

	/****使用find函数会自动缓存，更新的时候会清除缓存****/
	public function find($id, $reload = 0) {
		if ((!$id) && (!$this->options['where'])) {
			return false;
		}

		$cache = C('FIND_CACHE');
		/******不使用缓存***/
		if (!$cache) {
			return parent::find($id);
		}
		/******使用缓存***/
		if ($id) {
			$where = array($this->pk => $id);
		} else {
			$where = $this->options['where'];

		}

		$get_cache_key = $this->get_cache_key($where); //缓存键值
		$data = S($get_cache_key); //获得缓存
		if ($data === false || $reload == 1) {
			$r = parent::find($id);
			$data = $r ? $r : 0;
			if ($data[$this->pk]) {
				S($get_cache_key, $data);
				$this->set_cache($data[$this->pk], $get_cache_key);
			}

		}
		$this->options = array();
		if (!$where[$this->pk] && $data[$this->pk]) {
			$where = array($this->pk => $data[$this->pk]);
			return $this->where($where)->find();
		}

		return $data ? $data : NULL;
	}

	/***********主键加载一个*****/
	public function load($id = "") {
		if ($id) {
			unset($this->options['where']);
			$data = $this->find($id);
		}
		return $data;
	}

	/*******根据查询条件生成缓键值******/
	protected function get_cache_key($arr) {
		/******** 2、条件是字符串****/
		if ($where = $arr['_string']) {
			$where = str_replace("'", "", $where);
			$where = str_replace("(", "", $where);
			$where = str_replace(")", "", $where);
			$where = explode("and", $where);
			foreach ($where as $k => $one) {
				$row = explode("=", trim($one));
				$options[trim($row[0])] = trim(trim($row[1]), "'");
			}
		}
		/******** 条件是数组****/
		if (!$arr['_string']) {
			$options = $arr;
		}
		ksort($options);
		$this->key_options = $options;
		foreach ($options as $k => $v) {
			$options[$k] = "" . $v; //全部用字符串类型
		}
		$key = $this->name . "_" . md5(json_encode($options));
		return $key;
	}

	/***这个model里有唯一不重的主建多少缓存键值****/
	public function set_cache($pk, $key) {
		$name = $this->name . "_" . $pk;
		if ($key) {
			$data = S($name); //当前表，缓存了多少键值
			$data[$key] = 1;
			S($name, $data);
		} else {
			return S($name);
		}
	}

	/******删除缓存***/
	protected function del_cache($pk, $options) {
		$data = $this->set_cache($pk); //主键，缓存了多少键值
		foreach ($data as $key => $v) {
			//删除查询的缓存
			S($key, NULL);
		}
		$data = $this->set_cache("select"); //select，count 缓存了多少键值
		foreach ($data as $key => $v) {
			//删除查询的缓存
			S($key, NULL);
		}

	}

	/*****添加***/
	public function add($data = '', $options = array(), $replace = false) {
		$autopartition = C("autopartition");
		if ($this->pk == "id" && empty($data['id']) && $autopartition == 1) {
			$id = get_id($this->name);
			$data['id'] = $id;
		}
		$r = parent::add($data, $options, $replace);
		if ($r) {
			$this->del_cache($r); //返回主键
		}
		return $r;
	}

	/******删除数之后***/
	protected function _after_delete($data, $options) {
		$this->del_cache($data[$this->pk], $options);
	}

	/******插入之后之后***/
	protected function _after_insert($data, $options) {
		// $this->find($data[$this->pk]);	//生成缓存
		/*****删除查询的缓存**/
		$this->del_cache($data[$this->pk], $options);
		//S($this->name."_all",NULL);
		// $this->del_cache($data[$this->pk],$options);
	}

	/******更新之后之后***/
	protected function _after_update($data, $options) {
		//dump($data[$this->pk]);exit();
		//删除缓存
		$this->del_cache($data[$this->pk], $options);
	}

	/****更新操作***/
	public function save($data = '', $options = array()) {
		//dump($data);exit();
		if ($this->options['where']) {
			$where = $this->options['where'];
		}
		if ($data[$this->pk]) {
			$where = array($this->pk => $data[$this->pk]);
		}
		if (!$where) {
			throw_exception('更新条件不能为空');
		}
		$items = $this->where($where)->select();
		$count = 0;
		foreach ($items as $one) {
			$data[$this->pk] = $one[$this->pk];
			$r = parent::save($data, $options);
			if ($r) {
				$count++;
			}

		}
		return $count;
	}

	/****更新操作***/
	public function delete($options = array()) {
		$where = $this->options['where'];
		if (!is_array($options)) {
			$where = array($this->pk => $options);
		}
		if (!$where) {
			throw_exception('删除条件不能为空');
		}
		if (!is_array($options)) {
			$where = array($this->pk => $options);
		}
		$items = $this->where($where)->select();
		$count = 0;
		foreach ($items as $one) {
			$r = parent::delete($one[$this->pk]);
			if ($r) {
				$count++;
			}

		}
		return $count;
	}

	/***********清除缓存*****/
	public function resetTables() {
		S("Tables_in_boxphp", NULL);
		$this->Tables_in_boxphp();
	}

	/*********没有关联查询列表********/
	public function get($where = 1, $limit = "", $orderBy = "") {
		$where = $where ? $where : 1;
		$orderBy = $orderBy ? $orderBy : " $this->pk desc";
		/************从缓存中取得******/
		if (!$limit) {
			$key = $this->name . md5(json_encode($where) . "_" . $orderBy);
			if ($data = S($key)) {
				return $data;
			}
		}
		/******有limit是要分页的****/
		if ($limit) {
			$count = $this->where($where)->count();
			$page = setPager($count, $limit);
			$limit = $page['firstRow'] . "," . $page['listRows'];
		}
		$data = $this->where($where)->field($this->pk)->limit($limit)->order($orderBy)->select();
		if ($data) {
			foreach ($data as $one) {
				$re[] = $this->load($one[$this->pk]);
			}
		}
		if ($data) {
			if ($limit) {
				$data = array(
					'count' => $count,
					'list' => $re,
					'pager' => $page,
				);
			} else {
				$data = $re;
			}
		}
		//当查找全部的时候就缓存起来
		if (!$limit) {
			$this->set_cache("select", $key);
			S($key, $data);
		}
		return $data;
	}

	/****ByPks***/
	public function ByPks($pks) {
		$pks = is_array($pks) ? $ids : explode(",", $pks);
		foreach ($pks as $pk) {
			$row = $this->load($pk);
			if ($row) {
				$data[] = $row;
			}
		}
		return $data;
	}

	/*****根据字段来查询 tel***/
	public function ByFields($field, $vals) {
		$vals = is_array($vals) ? $vals : explode(",", $vals);
		if ($vals[0]) {
			foreach ($vals as $val) {
				$r = $this->where("$field='$val'")->field($this->pk)->find();
				$id = $r[$this->pk];
				$row = $this->load($id);
				if ($row) {
					$data[] = $row;
				}
			}
		}
		return $data;
	}

	public function ByField($field, $val) {
		$data = $this->ByFields($field, $val);
		return $data[0];
	}

	public function getIn($where = "", $field = "", $type = "string", $limit, $order) {
		if (!$where) {
			return false;
		}
		$r = array();
		if (!$field) {
			$field = $this->pk;
		}
		$this->where($where)->field($field);
		if ($limit) {
			$this->limit($limit);
		}
		if ($order) {
			$this->order($order);
		}
		$data = $this->select();
		if (!empty($data)) {
			foreach ($data as $one) {
				if (is_numeric($one[$field])) {
					$r[] = $one[$field];
				} else {
					$r[] = "'" . $one[$field] . "'";
				}
			}
			if ($type == "string") {
				$r = implode(",", $r);
			}
			return $r;
		} else {
			return false;
		}
	}

}
